Fork me on GitHub

Node.js 进程间通信

  • master.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var childprocess = require('child_process');
var worker = childprocess.fork('./worker.js');

console.log('pid in master:', process.pid);

worker.on('message', function(msg) {
console.log('1:', msg);
})
process.on('message', function(msg) {
console.log('2:', msg);
})

worker.send('---');
process.emit('message', '------');
  • worker.js
1
2
3
4
5
6
7
8
console.log('pid in worker:', process.pid);

process.on('message', function(msg) {
console.log('3:', msg);
});

process.send('===');
process.emit('message', '======');

运行结果:

1
2
3
4
5
6
7
$ node master.js
pid in master: 22229 // 主进程创建后打印其 pid
2: ------ // 主进程收到给自己发的消息
pid in worker: 22230 // 子进程创建后打印其 pid
3: ====== // 子进程收到给自己发的消息
1: === // 主进程收到来自子进程的消息
3: --- // 子进程收到来自主进程的消息

其中有两个有趣的点:

  1. 在主进程中,使用 worker.on('message', ...) 监听来自子进程的消息,使用 process.on('message', ...) 监听给自己发的消息。但是在子进程中,只有 process.on('message', ...) 一种消息监听方式,无法区分消息来源。

  2. 如果有给自己发消息的情况,则必须将对应的消息监听的代码放在消息发送代码前面,否则无法监听到该消息发送。例如将 master.js 的最后一行代码 process.emit('message', '------'); 放置到该文件第一行,则运行结果不会输出 2: ------

    如果不能控制消息监听代码和消息发送代码的先后顺序,可将给自己发送消息的代码改写为 setImmediate(process.emit.bind(process, 'message', ));